package inner;

class OuterClass {
    public int date1 = 1;
    int date2 = 2;
    private int date3 = 3;
    public static int date4 = 4;

    public void show() {
        System.out.println("OuterClass show:");
        System.out.println(this);
        System.out.println(date1 + " " + date2 + " " + date3 + " " + date4);
    }

    @Override //注解之一
    public String toString() {
        return "OuterClass{" +
                "date1=" + date1 +
                ", date2=" + date2 +
                ", date3=" + date3 +
                '}';
    }

    //实例内部类
    class InnerClass {
        public int date5 = 5;
        int date6 = 6;
        private int date7 = 7;
        //public static int date8=8;//居然不报错就离谱 待解决
        //实例内部类中不能定义静态成员变量,但在static 后加上 final 就行了
        public static final int date8 = 8;//此时date8 相当与一个常数不能够被修改了
        int date1 = 111;

        public void show() {
            System.out.println("InnerClass show:");
            //实例内部类的非静态方法中有一个指向外部类的引用 外部类名.this
            System.out.println(OuterClass.this + " " + this);
            //实例内部类可以直接访问外部类中的所有成员变量
            //System.out.println(date1 + " " + date2 + " " + date3 + " " + date4);

            //要是想访问外部类的同名成员变量可以像这样操作：
            System.out.println(OuterClass.this.date1 + " " + date2 + " " + date3 + " " + date4);
            /* 1 2 3 4 */

            System.out.println(date5 + " " + date6 + " " + date7 + " " + date8);
        }
    }

    //静态内部类
    static class InnerStaticClass {
        public int d1 = 11;
        int d2 = 22;
        private int d3 = 33;
        public static int d4 = 44;

        public void show() {
            System.out.println("InnerStaticClass show:");
            System.out.println(d1 + " " + d2 + " " + d3 + " " + d4 + " " + date4);
            //静态内部类中只能访问外部类中的静态成员
        }
    }

}

public class InnerTest {

    public static void main(String[] args) {
        //对象的打印 当类中有很多属性时我们手写show就会很蓝瘦 就可以通过idea来帮我们
        OuterClass outer=new OuterClass();
        System.out.println(outer);//inner.OuterClass@4eec7777 不是我们所期望的
        //但当我们加上toString方法后
        //OuterClass{date1=1, date2=2, date3=3}

    }

    public static void main3(String[] args) {
        //如何获取一个静态内部类
        OuterClass.InnerStaticClass staIn=new OuterClass.InnerStaticClass();
        //获取一个 静态内部类 不需要实例化一个外部类
        staIn.show();
        /*
         *InnerStaticClass show:
         *11 22 33 44 4
         */
        staIn.d1=666;
        OuterClass.InnerStaticClass staIn2=new OuterClass.InnerStaticClass();
        staIn2.show();
        /*
         * InnerStaticClass show:
         * 11 22 33 44 4  // d1没有改变
         */

    }

    public static void main2(String[] args) {
        //当实例内部类中有和外部类同名的成员变量会怎么样
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();

        inner.show();
        /*
         * InnerClass show:
         * Inner.OuterClass@16b98e56 Inner.OuterClass$InnerClass@7ef20235
         * 111 2 3 4 //会优先访问内部类的成员变量(就近原则)
         * 5 6 7 8
         */


    }

    public static void main1(String[] args) {
        //如何获取一个实例内部类的对象
        //1.
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();

        outer.show();
        /*OuterClass show:
         *Inner.OuterClass@3b07d329  //全路径 @ 对象地址的哈希值
         *1 2 3 4
         */
        inner.show();
        /*InnerClass show:
         *Inner.OuterClass@3b07d329 Inner.OuterClass$InnerClass@34a245ab
         *1 2 3 4
         *5 6 7 8
         */

        //2.
        OuterClass.InnerClass inner2 = new OuterClass().new InnerClass();
        inner2.show();
        /*InnerClass show:                       // $内部类 @ 对象地址哈希值
         *Inner.OuterClass@7cc355be Inner.OuterClass$InnerClass@6e8cf4c6
         *1 2 3 4
         *5 6 7 8
         */
    }
}
